<?php
/**
 * Bootstrap
 *
 *
 * @auth kim
 * @version 3.0
 *
 */

define('DS', DIRECTORY_SEPARATOR);
define('PS', PATH_SEPARATOR);

/**
 * Bootstrap class
 *
 * @auth kim
 * @version 3.0
 *
 */
final class Bootstrap
{
    const DEVELOPMENT   = 'development';
    const TESTING       = 'testing';
    const PRODUCTION    = 'production';

    const DIR_KBS       = 'Kbs';
    const DIR_APP       = 'application';
    const DIR_CONFIG    = 'configuration';

    const CLASS_KBS     = 'Kbs.php';

    /**
     * To force to get singleton instance
     *
     */
    static private $_instance = null;

    private function __construct() {}

    private function __clone() {}

    public static function getInstance()
    {
        if (null === self::$_instance) {
            self::$_instance = new self();
        }

        return self::$_instance;
    }

    /**
     * Project environment
     *
     */
    public static function setProjectEnvironment()
    {
        if (!defined('PROJECT_ENVIRONMENT')) {
            $env = @getenv('SECTION_CONFIG');

            switch ($env) {
                case self::DEVELOPMENT:
                case self::TESTING:
                    define('PROJECT_ENVIRONMENT', $env);
                    break;
                case self::PRODUCTION:
                default:
                    define('PROJECT_ENVIRONMENT', self::PRODUCTION);
                    break;
            }
        }
    }

    /**
     * Error display
     * To show the error or not
     *
     */
    public static function setErrorDisplay()
    {
        if (!defined('PROJECT_ENVIRONMENT')) {
            self::setProjectEnvironment();
        }

        ini_set('error_reporting', E_ALL | E_STRICT);
        
        switch (PROJECT_ENVIRONMENT) {
            case self::DEVELOPMENT:
                ini_set('display_startup_errors', 1);
                ini_set('display_errors', 1);
                break;
            case self::TESTING:
                ini_set('display_startup_errors', 0);
                ini_set('display_errors', 1);
                break;
            case self::PRODUCTION:
            default:
                ini_set('display_startup_errors', 0);
                ini_set('display_errors', 0);
                break;
        }
    }

    /**
     * The include paths
     *
     * Important !!
     * Please make sure you set the ZendFramework library within your project
     * even you have already set it in php.ini.
     * And make sure you put it in the first place of include paths !
     * Because this will straight affact the loading speed of Zend_Loader !!
     *
     */
    public static function setIncludePath()
    {
        if (!defined('PROJECT_ENVIRONMENT')) {
            self::setProjectEnvironment();
        }

        $paths = '';

        switch (PROJECT_ENVIRONMENT) {
            case self::DEVELOPMENT:
                $paths .= dirname(PROJECT_ROOT) . DS . 'ZendFramework' . DS . 'library' . PS;
                break;
            case self::TESTING:
                $paths .= dirname(PROJECT_ROOT) . DS . 'zend' . DS . 'library' . PS;
                break;
            case self::PRODUCTION:
            default:
                $paths .= dirname(PROJECT_ROOT) . DS . 'ZendFramework' . DS . 'library' . PS;
                break;
        }

        $paths = $paths
               . PROJECT_ROOT . DS . self::DIR_APP . DS . self::DIR_KBS . PS
               . PROJECT_ROOT . DS . self::DIR_CONFIG . DS . self::DIR_KBS . PS
               . get_include_path() . PS;

        set_include_path($paths);
    }

    /**
     * Application run
     * Combining the zend components
     *
     */
    public function run()
    {
        self::setProjectEnvironment();

        self::setErrorDisplay();
        
        self::setIncludePath();

        require_once(self::CLASS_KBS);

        try {

            /**
             * To initail the zend loader
             * usually is to registerAutoload classes
             * but this will slow down the website
             */
            Kbs::initLoader();

            /**
             * To initail the Zend_Controller_Front
             *
             */
            Kbs::initController();

            /**
             * To initail all the functionalities for the application !
             *
             */
            Kbs::initPlugin();

            /**
             * To output the result through Zend_Controller_Front::dispatch()
             *
             */
            Kbs::output();

        } catch (Exception $e) {

            /**
             * To handle all the exceptions
             *
             */
            Kbs::handleException($e);
        }
    }



}

